﻿using IOP.SgrA;
using IOP.SgrA.ECS;
using IOP.SgrA.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;

namespace VkSample83
{
    public class InputSystem : ComponentSystem
    {
        private Camera Camera;
        private Ambient Ambient = new Ambient(0.4f, 0.4f, 0.4f, 1.0f);

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contextManager"></param>
        public InputSystem()
        {
        }

        public override void Initialization()
        {
            ContextManager.Foreach<LightGroup>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                var obj = context.GetContextRenderObject();
                var render = context.GetContextRenderGroup();
                var camera = render.Camera;
                Camera = camera;
                PointLight light = obj.GetComponents<PointLight>().First();
                Span<Vector4> data = stackalloc Vector4[]
                {
                    new Vector4(camera.EyePosition, 1),
                    light.Position,
                    Ambient,
                    light.Strength,
                    light.Strength
                };
                Span<byte> p = MemoryMarshal.AsBytes(data);
                render.PushDataToTexture(p, 0, 0);
            });
        }

        public override void Update(TimeSpan lastStamp)
        {
            if (Input.GetMouseButtonState(MouseButton.ButtonLeft).Action == InputAction.Press)
            {
                Camera.EncircleForY(Vector3.Zero, Input.GetMousePositionDelta().X * 0.25f * MathF.PI / 180.0f);
            }
            ContextManager.Foreach<PMGroup>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                ref MVPMatrix mvp = ref context.GetMVPMatrix();
                mvp.ModelMatrix =
                Matrix4x4.CreateScale(group.Transform.Scale) *
                Matrix4x4.CreateFromQuaternion(group.Transform.Angle) *
                Matrix4x4.CreateScale(group.PMComponent.Scale2) *
                Matrix4x4.CreateTranslation(group.Transform.Position);
                context.PushToRenderGroup();
            });
            ContextManager.Foreach<LightGroup>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                var obj = context.GetContextRenderObject();
                var render = context.GetContextRenderGroup();
                var camera = render.Camera;
                PointLight light = obj.GetComponents<PointLight>().First();
                Span<Vector4> data = stackalloc Vector4[]
                {
                    new Vector4(camera.EyePosition, 1),
                    light.Position,
                    Ambient,
                    light.Strength,
                    light.Strength
                };
                Span<byte> p = MemoryMarshal.AsBytes(data);
                render.PushDataToTexture(p, 0, 0);
            });
        }
    }

    public struct LightGroup
    {
        public Entity Entity;
        public LightComponent Light;
    }
}
